class ScreenSnipper {
    constructor({ onCapture, snapDistance = 5 } = {}) {
        // 新增：截图完成后的回调
        this.onCapture = onCapture
        this.snapDistance = snapDistance; // 吸附阈值
        // 创建主画布
        this.canvas = document.createElement('canvas');
        this.canvas.id = 'snipCanvas';
        this.ctx = this.canvas.getContext('2d');
        document.body.appendChild(this.canvas);

        // 创建工具栏（保存 / 取消）
        this.toolbar = this.createToolbar();

        // 初始化变量
        this.video = null;  // 屏幕捕获视频元素
        this.stream = null; // 屏幕捕获流
        this.isSelecting = false; // 是否正在框选
        this.isDragging = false;  // 是否正在拖动选区
        this.startX = this.startY = this.endX = this.endY = undefined; // 选区坐标
        this.dragOffsetX = this.dragOffsetY = 0; // 拖动偏移量
        this.animationId = null; // requestAnimationFrame ID

        // 初始化事件绑定
        this.initEvents();
    }

    createToolbar() {
        // 创建浮动工具栏容器
        const toolbar = document.createElement('div');
        toolbar.style.cssText = `
            position: absolute;
            display: none;
            background: rgba(0,0,0,0.75);
            padding: 4px 8px;
            border-radius: 4px;
            gap: 6px;
            z-index: 9999;
        `;

        // 创建保存按钮
        const saveBtn = document.createElement('button');
        saveBtn.textContent = '保存';
        saveBtn.style.cssText = `
            background: #4CAF50;
            color: white;
            border: none;
            padding: 4px 8px;
            border-radius: 4px;
            cursor: pointer;
        `;
        saveBtn.onclick = () => this.captureSelection();

        // 创建取消按钮
        const cancelBtn = document.createElement('button');
        cancelBtn.textContent = '取消';
        cancelBtn.style.cssText = `
            background: #f44336;
            color: white;
            border: none;
            padding: 4px 8px;
            border-radius: 4px;
            cursor: pointer;
        `;
        cancelBtn.onclick = () => this.stopCapture();

        // 工具栏添加按钮
        toolbar.appendChild(saveBtn);
        toolbar.appendChild(cancelBtn);
        document.body.appendChild(toolbar);
        return toolbar;
    }

    initEvents() {
        // 鼠标事件绑定
        this.canvas.onmousedown = e => this.handleMouseDown(e);
        this.canvas.onmousemove = e => this.handleMouseMove(e);
        this.canvas.onmouseup = () => this.handleMouseUp();
        this.canvas.oncontextmenu = e => e.preventDefault(); // 禁用右键菜单

        // 键盘事件（ESC / Enter）
        window.addEventListener('keydown', e => this.handleKeyDown(e));

        // 页面关闭前停止捕获
        window.addEventListener('beforeunload', () => this.stopCapture());
    }

    async start() {
        try {
            // 请求屏幕共享权限
            this.stream = await navigator.mediaDevices.getDisplayMedia({ video: true });

            // 创建视频元素播放屏幕流
            this.video = document.createElement('video');
            this.video.srcObject = this.stream;
            await this.video.play();

            // 设置画布大小为屏幕分辨率
            this.canvas.width = this.video.videoWidth;
            this.canvas.height = this.video.videoHeight;
            this.canvas.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                z-index: 9998;
                cursor: crosshair;
            `;

            // 启动绘制循环
            this.startDrawing();
        } catch (err) {
            console.error("Screen capture failed:", err);
        }
    }

    startDrawing() {
        // 确保只运行一个动画循环
        cancelAnimationFrame(this.animationId);
        this.drawVideoToCanvas();
    }

    drawVideoToCanvas() {
        // 清除画布
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        // 绘制屏幕视频
        this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);

        // 如果有选区，绘制半透明遮罩和选区框
        if ((this.isSelecting || this.isDragging || this.startX !== undefined) && this.startX !== undefined) {
            const x = Math.min(this.startX, this.endX);
            const y = Math.min(this.startY, this.endY);
            const w = Math.abs(this.endX - this.startX);
            const h = Math.abs(this.endY - this.startY);

            // 半透明遮罩
            this.ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
            this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

            // 在选区内重新绘制原视频
            this.ctx.drawImage(this.video, x, y, w, h, x, y, w, h);

            // 选区边框
            this.ctx.strokeStyle = "#00f";
            this.ctx.lineWidth = 2;
            this.ctx.strokeRect(x, y, w, h);

            // 选区尺寸提示
            this.ctx.fillStyle = "rgba(0,0,0,0.6)";
            this.ctx.fillRect(x, y - 20, 80, 20);
            this.ctx.fillStyle = "#fff";
            this.ctx.font = "12px sans-serif";
            this.ctx.fillText(`${w} x ${h}`, x + 5, y - 5);

            // 工具栏定位到选区右下角
            if (!this.isSelecting && !this.isDragging && w > 5 && h > 5) {
                this.toolbar.style.left = (x + w + 10) + "px";
                this.toolbar.style.top = (y + h + 10) + "px";
                this.toolbar.style.display = "flex";
            }
        }
        // 循环绘制
        this.animationId = requestAnimationFrame(() => this.drawVideoToCanvas());
    }

    snapToEdges() {
        const rectW = Math.abs(this.endX - this.startX);
        const rectH = Math.abs(this.endY - this.startY);

        // 左边
        if (Math.abs(this.startX) <= this.snapDistance) {
            this.startX = 0
            this.endX = rectW
        }

        // 右边
        if (Math.abs(this.canvas.width - (this.startX + rectW)) <= this.snapDistance) {
            this.startX = this.canvas.width - rectW
            this.endX = this.canvas.width
        }

        // 上边
        if (Math.abs(this.startY) <= this.snapDistance) {
            this.startY = 0;
            this.endY = rectH;
        }
        // 下边
        if (Math.abs(this.canvas.height - (this.startY + rectH)) <= this.snapDistance) {
            this.startY = this.canvas.height - rectH;
            this.endY = this.canvas.height;
        }
    }

    handleMouseDown(e) {
        const rectX = Math.min(this.startX || 0, this.endX || 0);
        const rectY = Math.min(this.startY || 0, this.endY || 0);
        const rectW = Math.abs((this.endX || 0) - (this.startX || 0));
        const rectH = Math.abs((this.endY || 0) - (this.startY || 0));

        // 右键拖动
        if (e.button === 2 && rectW > 5 && rectH > 5) {
            // 判断鼠标是否在选区范围内
            if (e.offsetX >= rectX && e.offsetX <= rectX + rectW &&
                e.offsetY >= rectY && e.offsetY <= rectY + rectH) {
                this.isDragging = true;
                // 记录鼠标相对选区左上角的偏移
                /**
                 这是关键：记录鼠标点击位置相对选区左上角的距离
                    例如：

                    选区左上角在 (100, 100)

                    鼠标在 (120, 130) 点击

                    偏移量就是 (20, 30)

                    这个偏移量会在拖动时用到，让选区在拖动过程中保持鼠标在框里的同一个点，而不是跳到左上角
                 */
                this.dragOffsetX = e.offsetX - rectX;
                this.dragOffsetY = e.offsetY - rectY;
                this.toolbar.style.display = "none";
                return;
            }
        }

        // 左键开始新选区
        if (e.button === 0) {
            this.isSelecting = true;
            this.startX = e.offsetX;
            this.startY = e.offsetY;
            this.endX = this.startX;
            this.endY = this.startY;
            this.toolbar.style.display = "none";
        }
    }

    handleMouseMove(e) {
        if (this.isSelecting) {
            // 调整选区大小
            this.endX = e.offsetX;
            this.endY = e.offsetY;
        } else if (this.isDragging) {
            // 拖动选区位置 获取当前选区的宽高
            const rectW = Math.abs(this.endX - this.startX);
            const rectH = Math.abs(this.endY - this.startY);
            // 计算新的左上角位置
            this.startX = e.offsetX - this.dragOffsetX;
            this.startY = e.offsetY - this.dragOffsetY;
            // 更新右下角位置
            this.endX = this.startX + rectW;
            this.endY = this.startY + rectH;
            this.snapToEdges()
        }
                console.log(this.startX, this.startY, this.endX, this.endY) 
    }

    handleMouseUp() {
        this.isSelecting = false;
        this.isDragging = false;
    }

    handleKeyDown(e) {
        const step = e.shiftKey ? 10 : 1
        // 微调选区
        if (this.startX !== undefined && this.endX !== undefined) {
            const rectW = Math.abs(this.endX - this.startX);
            const rectH = Math.abs(this.endY - this.startY);
            if (e.key === 'ArrowUp') {
                this.startY = Math.max(0, this.startY - step)
                this.endY = this.startY + rectH
            }
            if (e.key === 'ArrowDown') {
                this.startY = Math.min(this.canvas.height- rectH, this.startY + step)
                this.endY = this.startY + rectH
            }

            if (e.key === 'ArrowLeft') {
                this.startX = Math.max(0, this.startX - step)
                this.endX = this.startX + rectW
            }

            if (e.key === 'ArrowRight') {
                this.startX = Math.min(this.canvas.width - rectW, this.startX + step);
                this.endX = this.startX + rectW;
            }
            this.snapToEdges()
        }


        // ESC 取消截图
        if (e.key === 'Escape') {
            this.stopCapture()
        } 
        // Enter 保存
        if (e.key === 'Enter') {
             if (!this.isSelecting && this.startX !== undefined && this.endX !== undefined) {
                this.captureSelection();
            }
        }
    }

    captureSelection() {
        const x = Math.min(this.startX, this.endX);
        const y = Math.min(this.startY, this.endY);
        const w = Math.abs(this.endX - this.startX);
        const h = Math.abs(this.endY - this.startY);

        if (w < 5 || h < 5) return; // 防止选区太小

        // 创建临时画布导出选区
        const tempCanvas = document.createElement("canvas");
        tempCanvas.width = w;
        tempCanvas.height = h;
        const tempCtx = tempCanvas.getContext("2d");
        tempCtx.drawImage(this.canvas, x, y, w, h, 0, 0, w, h);

        // 转为 Base64 并下载
        const dataUrl = tempCanvas.toDataURL("image/png");
        // 新增：回调优先，否则下载
        if (typeof this.onCapture === 'function') {
            this.onCapture(dataUrl)
        } else {
            this.downloadImage(dataUrl, "screenshot_" + new Date().getTime() + ".png");
        }
        // 停止捕获
        this.stopCapture();
    }

    downloadImage(dataUrl, filename) {
        const a = document.createElement("a");
        a.href = dataUrl;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    }

    stopCapture() {
        cancelAnimationFrame(this.animationId);
        if (this.stream) {
            this.stream.getTracks().forEach(track => track.stop());
        }
        this.canvas.width = 0;
        this.canvas.height = 0;
        this.toolbar.style.display = "none";
        this.startX = this.startY = this.endX = this.endY = undefined;
    }
}
